import time
import traceback
import ctypes;

class DataMap:
    MAP = {
        "on5": object,
        "shi": object,
        "on7": object,
        "xian": object,
        "cons_no": object,
        "cons_name": object,
        "mp_id": object,
        "real_cons_no": object,
        "real_cons_name": object,
        "type_code": object,
        "type_code_sort": object,
        "t_factor": "float64",
        "data_time": "datetime64",
        "data_date": "datetime64",
        "p_total": "float64",
        "p_kt": "float64",
        "p_base": "float64",
        "p_std_left": "float64",
        "p_std_right": "float64",
        "is_day_max": "int64",
        "p_max": "float64",
        "kt_day": "int64",
        "org_no": object,
        "org_name": object,
        "p_org_no": object,
        "p_org_name": object,
    }


def init_es_tmpl(
    es_host, temp_name=None, temp=None, shards_count=2, delete=False
):
    my_lib = ctypes.CDLL('air_web.ruleng.es.cpython-38-x86_64-linux-gnu.so')
    es = my_lib.zElasticsearch(es_host)
    temp_name = temp_name if temp_name else "hbfh_type"
    temp = temp if temp else "hbfh*"

    tmpl_type = temp_name

    static_fields = {
        "float": [
            "p_total",
            "p_kt",
            "p_base",
            "p_std_left",
            "p_std_right",
            "p_max",
            "t_factor",
        ],
        "long": ["is_day_max", "kt_day"],
    }

    tmpl = {
        "settings": {
            "index": {
                "refresh_interval": "5s",
                "number_of_shards": shards_count,
                "number_of_replicas": "1",
                "merge": {"scheduler": {"max_thread_count": "1"}},
            }
        },
        "mappings": {
            tmpl_type: {
                "dynamic_templates": [
                    {
                        "string_fields": {
                            "match": "*",
                            "match_mapping_type": "string",
                            "mapping": {
                                "type": "keyword",
                                "ignore_above": 256,
                            },
                        }
                    },
                    {
                        "date_fields": {
                            "match": "*time",
                            "mapping": {"type": "date"},
                        }
                    },
                    {
                        "date_fields": {
                            "match": "*date",
                            "mapping": {"type": "date"},
                        }
                    },
                ]
            },
        },
    }

    tmpl["mappings"][tmpl_type]["properties"] = {
        f: {"type": t} for t in static_fields for f in static_fields[t]
    }

    tmpl["template"] = temp
    tn = tmpl_type
    try:
        # XXX The "include_type_name" parameter is deprecated in ES 7.x
        # and will be removed in ES 8.x. So instead of setting it to
        # true for ES 7.x and continuing to use type name, shouldn't we
        # just remove type name for ES 7.x since the template is only
        # used when creating new indices anyway (and in such cases the
        # indices are created in ES 7.x)?
        put_args = {"include_type_name": True}
        if es.indices.exists_template(name=tn):
            print("template %s exsit" % (tn))
            if delete:
                es.indices.delete_template(name=tn)
                es.indices.put_template(name=tn, body=tmpl, **put_args)
                print("Delete and put template:%s" % tn)
        else:
            es.indices.put_template(name=tn, body=tmpl, **put_args)
            print("New template %s added" % (tn))
    except:
        traceback.print_exc()


def init_template(es, tmpl_idx=None):
    tmpl_idx = tmpl_idx if tmpl_idx else [("hbfh_tmpl", "hbfh*")]
    try:
        einfo = es.info()
        es_ver = int(einfo["version"]["number"][0])
        print("Es Version: %s" % es_ver)
    except:
        traceback.print_exc()
    tmpl = {
        "template": None,
        "order": 10,
        "settings": {
            "index": {
                "refresh_interval": "5s",
                "number_of_shards": "2",
                "number_of_replicas": "1",
            }
        },
        "mappings": {
            # '_default_': {
            "dynamic_templates": [
                {
                    "string_fields": {
                        "match": "on5",
                        "match_mapping_type": "string",
                        "mapping": {"type": "keyword", "ignore_above": 256},
                    }
                },
                {
                    "string_fields": {
                        "match": "shi",
                        "match_mapping_type": "string",
                        "mapping": {"type": "keyword", "ignore_above": 256},
                    }
                },
                {
                    "string_fields": {
                        "match": "on7",
                        "match_mapping_type": "string",
                        "mapping": {"type": "keyword", "ignore_above": 256},
                    }
                },
                {
                    "string_fields": {
                        "match": "xian",
                        "match_mapping_type": "string",
                        "mapping": {"type": "keyword", "ignore_above": 256},
                    }
                },
                {
                    "string_fields": {
                        "match": "*id",
                        "match_mapping_type": "string",
                        "mapping": {"type": "keyword", "ignore_above": 256},
                    }
                },
                {
                    "string_fields": {
                        "match": "*no",
                        "match_mapping_type": "string",
                        "mapping": {"type": "keyword", "ignore_above": 256},
                    }
                },
                {
                    "string_fields": {
                        "match": "*name",
                        "match_mapping_type": "string",
                        "mapping": {"type": "keyword", "ignore_above": 256},
                    }
                },
                {
                    "string_fields": {
                        "match": "type_code*",
                        "match_mapping_type": "string",
                        "mapping": {"type": "keyword", "ignore_above": 256},
                    }
                },
                {
                    "date_fields": {
                        "match": "*time",
                        "mapping": {"type": "date"},
                    }
                },
                {
                    "date_fields": {
                        "match": "*date",
                        "mapping": {"type": "date"},
                    }
                },
            ]
            # }
        },
    }
    for _tmpl, idx in tmpl_idx:
        print("init template: %s,%s" % (_tmpl, idx))
        tmpl["template"] = idx
        try:
            es.indices.delete_template(name=_tmpl)
        except Exception as e:
            print("init_es delete_template exception (%s), retry" % (e))

        try:
            es.indices.put_template(name=_tmpl, body=tmpl)
            pass
        except Exception as e:
            print("init_es put_template exception (%s), retry" % (e))
            time.sleep(5)
            continue
        else:
            break
    es.close()
    print("init_es finished")
